-module(stats).
-export([
	average_time_for_request/1,
	average_time_for_request_at_node_and_resource/3,
	fastest_resources_for_request/1
]).
-include_lib("mnemosyne/include/mnemosyne.hrl").
-include("drproxy.hrl").

average_time_for_request_at_node_and_resource(Uri, Node, Resource) ->
    F = fun() ->
                Q = query [E.response_seconds || E <- table(timestamp),
                                    E.uri = Uri,
									E.client = Node,
									E.resource = Resource] end,
                mnemosyne:eval(Q)
        end,
    case mnesia:transaction(F) of
		{atomic, []} ->
			{error, no_request_for_uri, Uri};
		{atomic, M} ->
			lists:foldl(fun (X, A) -> A + X end, 0, M) / length(M)
	end.

average_time_for_request(Uri) ->
    F = fun() ->
                Q = query [E.response_seconds || E <- table(timestamp),
                                    E.uri = Uri,
									E.created_at > (utils:unix_time() - 60*5)] end,
                mnemosyne:eval(Q)
        end,
    case mnesia:transaction(F) of
		{atomic, []} ->
			{error, no_request_for_uri, Uri};
		{atomic, M} ->
			lists:foldl(fun (X, A) -> A + X end, 0, M) / length(M)
	end.

fastest_resources_for_request(Uri) ->
    F = fun() ->
                Q = query [{{E.client, E.resource}, E.response_seconds, E.request_seconds, E.attempts} || E <- table(timestamp),
                                    E.uri = Uri,
									E.created_at > (utils:unix_time() - 60*5)] end,
                mnemosyne:eval(Q)
        end,
    case mnesia:transaction(F) of
		{atomic, []} ->
			{error, no_request_for_uri};
		{atomic, M} ->
			ToMap = lists:foldl(fun({Key, V1, V2, V3}, Acc) ->
				case lists:keysearch(Key, 1, Acc) of
					false ->
						[{Key, {V1, 1}, {V2, 1}, {V3, 1}} | Acc];
					{value, {Key, {VR1, S1}, {VR2, S2}, {VR3, S3}}} ->
						NewValue = {Key, {VR1 + V1, S1 + 1}, {VR2 + V2, S2 + 1}, {VR3 + V3, S3 + 1}},
						lists:keyreplace(Key, 1, Acc, NewValue)
				end
			end, [], M),

			ToSort = lists:map(fun({Key, {V1, S1}, {V2, S2}, {V3, S3}}) ->
				{Key, V1/S1, V2/S2 - V1/S1, V3/S3, S1}
			end, ToMap),

			lists:keysort(2, ToSort)
	end.